﻿using UnityEngine;
using System.Collections;
using System;
[RequireComponent(typeof(BoxCollider))]
public class PlayerPhysics : MonoBehaviour
{
    public float maxSpeed;
    public float curSpeedHor;
    public float curSpeedVert;
    public float acceleration;
    public float gravityForce;
    public float jumpForce;
    public Animator animator;
    public RaycastHit hitInfo;
    public BoxCollider collider;
    public string charDirection = "forward";
    public MoveDirection cDir = MoveDirection.Right;
    public GameObject character;

    public LayerMask mask;

    private float rayOffset = 0.5f;

    private bool landed = false;
    public float skin = 0.005f;
    public void MoveHorizontal(float targetDir)
    {
        float targetSpeed = targetDir * maxSpeed * Time.deltaTime;
        float incDir = Mathf.Sign(targetSpeed - curSpeedHor);

        curSpeedHor += acceleration * Time.deltaTime * incDir;
        curSpeedHor = (incDir == Mathf.Sign(targetSpeed - curSpeedHor)) ? curSpeedHor : targetSpeed;
        if (targetDir < 0 && IsHorizontalCollision(targetDir))
            curSpeedHor = 0;
        if (targetDir > 0 && IsHorizontalCollision(targetDir))
            curSpeedHor = 0;
        transform.Translate(new Vector2(curSpeedHor, 0));
    }
    public void AnimatorParams()
    {
        animator.SetFloat("HorSpeed", Mathf.Abs(curSpeedHor) * 10);
        if (landed == true)
            animator.SetBool("Jump", false);
    }
    public void Jump()
    {
        if (landed)
        {
            curSpeedVert = jumpForce * 0.015f;
            transform.Translate(new Vector2(0, curSpeedVert));
            animator.SetBool("Jump", true);
        }
        
    }
    public void MoveVertical(float targetDir)
    {
        float targetSpeed = targetDir * maxSpeed * Time.deltaTime;
        float incDir = Mathf.Sign(targetSpeed - curSpeedHor);

        curSpeedVert += acceleration * Time.deltaTime * incDir;
        curSpeedVert = (incDir == Mathf.Sign(targetSpeed - curSpeedVert)) ? curSpeedVert : targetSpeed;
        if (targetDir < 0 && IsGroundCollision())
            curSpeedVert = 0;
        if (targetDir > 0 && IsRoofCollision())
            curSpeedVert = 0;
        transform.Translate(new Vector2(0, curSpeedVert));
    }
    void Update()
    {
        Gravity();
        IsRoofCollision();
        ChangeCharDirection();
        AnimatorParams();
    }
    public void Gravity()
    {
        if (!IsGroundCollision() && landed == false)
        {
            curSpeedVert -= gravityForce * Time.deltaTime;
            transform.Translate(new Vector2(0, curSpeedVert));
        }
    }
    bool IsGroundCollision()
    {
        if (curSpeedVert <= 0)
        {
            var c = collider;
            var p = transform.position;

            float rayDistance = Mathf.Abs(curSpeedVert) + rayOffset+skin;
            
            for (int i = -1; i < 2; i++)
            {
                float x = p.x + c.center.x + c.size.x / 2 * i;
                float y = p.y + c.center.y - c.size.y / 2 + rayOffset;
                Ray ray = new Ray(new Vector2(x, y), Vector3.down);
                //Debug.DrawRay(ray.origin, ray.direction, Color.green);
                if (Physics.Raycast(ray, out hitInfo, Mathf.Abs(rayDistance), mask))
                {
                    float distance = Vector2.Distance(ray.origin, hitInfo.point);
                    transform.Translate(new Vector2(0, -distance + rayOffset ));
                    landed = true;
                    curSpeedVert = 0;
                    return true;
                }
            }
        }
        landed = false;
        
        return false;
    }
    public void ChangeCharDirection()
    {
        if(curSpeedHor < 0 && charDirection != "backward")
        {
            charDirection = "backward";
            character.transform.Rotate(0, 180, 0);
        }
        else if(curSpeedHor > 0 && charDirection != "forward")
        {
            charDirection = "forward";
            character.transform.Rotate(0, -180, 0);
        }
    }
    bool IsRoofCollision()
    {
        if (curSpeedVert > 0)
        {
            var c = collider;
            var p = transform.position;
            
            float rayDistance = curSpeedVert + rayOffset;
            
            for (int i = -1; i < 2; i++)
            {
                float x = p.x + c.center.x + c.size.x / 2 * i;
                float y = p.y + c.center.y + c.size.y/2 - rayOffset;
                Ray ray = new Ray(new Vector2(x, y), new Vector2(0, rayDistance));
                Debug.DrawRay(ray.origin, new Vector2(0, rayDistance), Color.green);
                if (Physics.Raycast(ray, out hitInfo, Mathf.Abs(rayDistance), mask))
                {
                    
                    float distance = Vector2.Distance(ray.origin, hitInfo.point);
                    
                    transform.Translate(new Vector2(0, +distance - rayOffset - skin));
                    curSpeedVert = 0;
                    return true;
                }
            }
        }

        return false;
    }

    bool IsHorizontalCollision(float dir)
    {
        if (curSpeedHor != 0)
        {
            var c = collider;

            var p = transform.position;
            for (int i = -1; i < 2; i++)
            {
                float x = p.x + collider.center.x + collider.size.x / 2 * dir;
                float y = p.y + collider.center.y + collider.size.y / 2 * i;
                Ray ray = new Ray(new Vector2(x, y), new Vector2(dir, 0));
                Debug.DrawRay(ray.origin, ray.direction, Color.green);
                if (Physics.Raycast(ray, out hitInfo, Mathf.Abs(curSpeedHor), mask))
                {
                    float distance = Vector2.Distance(ray.origin, hitInfo.point);
                    transform.Translate(new Vector2((distance - skin) * dir, 0));
                    return true;
                }
            }
        }
        return false;
    }
    void Start()
    {
        collider = GetComponent<BoxCollider>();
        animator = GetComponentInChildren<Animator>();
        character = GameObject.Find("Character");
    }

    #region seb
    //// Use this for initialization
    //public BoxCollider boxCollider;
    //public Vector3 cs;
    //public Vector3 cc;
    //public LayerMask mask;

    //public float skin = .005f;
    //public Ray ray;
    //public RaycastHit hit;
    //[HideInInspector]
    //public bool landed = false;

    //public float dist;
    //public void Move(Vector2 amountToMove)
    //{
    //    Vector2 finalTransform = new Vector2();
    //    finalTransform.x = amountToMove.x;
    //    finalTransform.y = amountToMove.y;
    //    Vector2 p = t.position;
    //    for (int i = 0; i < 3; i++)
    //    {
    //        float dir = Mathf.Sign(amountToMove.y);
    //        float rayx = p.x - cs.x / 2 + cs.x / 2 * i;
    //        float rayy = p.y + cs.y / 2 * dir;

    //        ray.origin = new Vector2(rayx, rayy);
    //        ray.direction = new Vector2(0, dir);
    //        Debug.DrawRay(ray.origin, ray.direction);

    //            if (Physics.Raycast(ray, out hit, Mathf.Abs(finalTransform.y)+0.1f, mask))
    //            {
    //                float dist = Vector2.Distance(ray.origin, hit.point);

    //                if (dist > skin)
    //                {
    //                    finalTransform.y = -dist + skin;
    //                }
    //                else
    //                {
    //                    finalTransform.y = 0;
    //                }
    //                landed = true;
    //                break;
    //            }
    //    }


    //    t.Translate(finalTransform);

    //}
    //public void DrawRays()
    //{


    //    //float dir = -1;

    //}
    //void Start()
    //{
    //    boxCollider = GetComponent<BoxCollider>();
    //    cs = boxCollider.size;
    //    cc = boxCollider.center;
    //}


    #endregion
}
